package com.ouc.oceanBase.controller;


import com.ouc.common.annotation.Log;
import com.ouc.common.config.properties.ApplicationProperties;
import com.ouc.common.constant.VariableName;
import com.ouc.common.core.controller.BaseController;
import com.ouc.common.core.domain.AjaxResult;
import com.ouc.common.entity.NcData;
import com.ouc.common.enums.BusinessType;
import com.ouc.common.ncRead.NcDao;
import com.ouc.common.utils.DateUtils;
import com.ouc.common.utils.StringUtils;
import com.ouc.common.utils.file.FileUtils;
import com.ouc.oceanBase.domain.EddySet;
import com.ouc.oceanBase.entity.ContourData;
import com.ouc.oceanBase.entity.EddyCenterInfo;
import com.ouc.oceanBase.entity.FactorCondition;
import com.ouc.oceanBase.entity.JData;
import com.ouc.oceanBase.pojo.NcCubeData;
import com.ouc.oceanBase.service.EddyCharacterService;
import com.ouc.oceanBase.service.EddySetService;
import com.ouc.oceanBase.service.FeatureService;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ucar.nc2.NetcdfFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static com.ouc.common.constant.NcConstants.ANTICYCLONIC;
import static com.ouc.common.constant.NcConstants.CYCLONIC;

/**
 * 特征识别可视化接口
 *
 * @author B504
 */
@RestController
@CrossOrigin
@RequestMapping("/featureVisual")
public class FeatureController extends BaseController {
//  @Autowired
//  private ProfileService profileService;

  @Autowired
  private EddySetService eddySetService;

  @Autowired
  EddyCharacterService eddyCharacterService;

  @Autowired
  private NcDao ncDao;

  @Autowired
  private FeatureService featureService;

  @Autowired
  private ApplicationProperties applicationProperties;

//  @RequestMapping(value = "/getProFileData")
//  @Log(title = "绘制剖面", businessType = BusinessType.DRAW, isSaveResponseData = false)
//  public AjaxResult getProFileData(@RequestParam("filePath") String filePath,
//                                   FactorCondition factorCondition,
//                                   @RequestParam(value = "startLevel", required = false) Integer startLevel,
//                                   @RequestParam(value = "endLevel", required = false) Integer endLevel) {
//    try {
//      Integer[] levels;
//      if (startLevel == null && endLevel == null) {
//        levels = null;
//      } else {
//        levels = new Integer[]{startLevel, endLevel};
//      }
//      NetcdfFile ncFile = NetcdfFile.open(filePath);
//      return AjaxResult.success(profileService.getProfileData(ncFile, factorCondition.getVariableName(),
//          new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
//          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, levels));
//    } catch (Exception e) {
//      e.printStackTrace();
//      return AjaxResult.error("获取剖面数据失败");
//    }
//  }

  @RequestMapping(value = "getNcDataFromAllLevel")
  @Log(title = "绘制剖面", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getNcDataFromAllLevel(@RequestParam("filePath") String filePath,
                                          FactorCondition factorCondition) {
    try {
      ContourData<NcCubeData> contourData = featureService.getNcCubeData(filePath, factorCondition.getVariableName(), new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, null);
      return AjaxResult.success(contourData);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取数据失败由于:" + e.getMessage());
    }
  }

  /**
   * 从python生成的nc文件中提取涡旋信息
   * 只需要经度和纬度即可
   *
   * @param filePath nc文件路径
   * @return
   */
  @RequestMapping(value = "/getEddyOfPet")
  @ResponseBody
  @RequestBody
  public AjaxResult getEddyOfGlobe(@RequestParam("filePath") String filePath) {

    String[] outFilePath = new String[]{new File(filePath).getParent() + File.separator + ANTICYCLONIC + "_" + StringUtils.getContinuityNum(FileUtils.getName(filePath), 8) + ".nc",
        new File(filePath).getParent() + File.separator + CYCLONIC + "_" + StringUtils.getContinuityNum(FileUtils.getName(filePath), 8) + ".nc"};
    EddyCenterInfo hotCenter = new EddyCenterInfo();
    EddyCenterInfo coldCenter = new EddyCenterInfo();
    List<EddySet> eddySetList = new ArrayList<>();
    for (String s : outFilePath) {
      try (NetcdfFile ncFile = NetcdfFile.open(s)) {
        Map<String, NcData> ncDataMap = ncDao.getNcData(ncFile);
        //  如果是暖涡
        if (FileUtils.getName(s).matches(".*Anticyclonic.*")) {
          float[] lonArr = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.LON).getShortName()).getData1D();
          float[] latArr = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.LAT).getShortName()).getData1D();
          float[] radiusArr = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.RADIUS).getShortName()).getData1D();
          float[][] outlineLat = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.EFFECTIVELAT).getShortName()).getData2D();
          float[][] outlineLon = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.EFFECTIVELON).getShortName()).getData2D();
          hotCenter.setOutlineLat(outlineLat);
          hotCenter.setOutlineLon(outlineLon);
          hotCenter.setLonArr(lonArr);
          hotCenter.setLatArr(latArr);
          hotCenter.setRadiusArr(radiusArr);
          hotCenter.setType(2);
          insertEddySet(s, hotCenter, eddySetList);
        } //  如果是冷涡
        else if (FileUtils.getName(s).matches(".*Cyclonic.*")) {
          float[] lonArr = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.LON).getShortName()).getData1D();
          float[] latArr = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.LAT).getShortName()).getData1D();
          float[] radiusArr = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.RADIUS).getShortName()).getData1D();
          float[][] outlineLat = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.EFFECTIVELAT).getShortName()).getData2D();
          float[][] outlineLon = ncDataMap.get(ncDao.getVariable(ncFile, VariableName.EFFECTIVELON).getShortName()).getData2D();

          coldCenter.setOutlineLon(outlineLon);
          coldCenter.setOutlineLat(outlineLat);
          coldCenter.setLonArr(lonArr);
          coldCenter.setLatArr(latArr);
          coldCenter.setRadiusArr(radiusArr);
          coldCenter.setType(1);
          insertEddySet(s, coldCenter, eddySetList);
        }
      } catch (Exception e) {
        e.printStackTrace();
        return AjaxResult.error("获取文件失败");
      }
    }
    return AjaxResult.success(new Object[]{coldCenter, hotCenter});
  }

  /**
   * 插入涡旋到临时表
   *
   * @param filePath       nc文件路径
   * @param eddyCenterInfo 涡旋中心信息
   * @param eddySetList    临时涡旋信息
   * @return
   */
  private boolean insertEddySet(String filePath, EddyCenterInfo eddyCenterInfo, List<EddySet> eddySetList) {
    try {
      for (int i = 0; i < eddyCenterInfo.getLatArr().length; i++) {
        EddySet eddySet = new EddySet();
        eddySet.setEddyId(eddySetList.size() + 1);
        eddySet.setEddyDate(DateUtils.parseDate(StringUtils.getContinuityNum(FileUtils.getName(filePath), 8)));
        eddySet.setEddyType(eddyCenterInfo.getType());
        eddySet.setEddyRadius(eddyCenterInfo.getRadiusArr()[i]);
        eddySet.setEddyLon(eddyCenterInfo.getLonArr()[i]);
        eddySet.setEddyLat(eddyCenterInfo.getLatArr()[i]);
        eddySet.setEddyCountourLon(Arrays.toString(eddyCenterInfo.getOutlineLon()[i]));
        eddySet.setEddyCountourLat(Arrays.toString(eddyCenterInfo.getOutlineLat()[i]));
        eddySet.setEddySource(1);
        eddySetList.add(eddySet);
      }
      //  批量插入数据表
      eddySetService.insertByBach(eddySetList);
      return true;

    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

  /**
   * 获取深度学习图片
   *
   * @param pngName 图片名称
   * @return
   */
  @RequestMapping("/getDeepLearnPng")
  @ResponseBody
  public AjaxResult getDeepLearnEddy(@RequestParam(value = "pngName") String pngName) {
    try {
      String filePath = String.join(File.separator, applicationProperties.getNavData(), pngName);
      return AjaxResult.success(FileUtils.getFileByteArray(new File(filePath)));
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取图片失败");
    }

  }

  /**
   * 流场可视化通过d3方法
   * 因为特征可视化的水平切面需要所以在这里保留
   *
   * @param filePath        文件路径
   * @param factorCondition 可视化条件
   * @param time            时间
   * @return
   */
  @RequestMapping("/getCurrentByD3")
  @Log(title = "流场可视化（通过d3）", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getCurrentByD3(@RequestParam("filePath") String filePath,
                                   FactorCondition factorCondition,
                                   @RequestParam(value = "time", required = false) Integer time) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      return AjaxResult.success(eddyCharacterService.getFlowGridData(ncFile, new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time));
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取流场数据失败可能是由于" + e.getMessage());
    }

  }

//  /**
//   * 获取涡旋剖面数据
//   *
//   * @param filePath     文件路径
//   * @param variableName 变量名
//   * @param lon          经度
//   * @param lat          纬度
//   * @param lonDiffer    经度偏移
//   * @param latDiffer    纬度偏移
//   * @param degree       与x轴夹角
//   * @param radianFlag   是否是弧度
//   * @return
//   */
//  @RequestMapping("/getEddyProFileData")
//  @Log(title = "获取涡旋剖面数据", businessType = BusinessType.DRAW, isSaveResponseData = false)
//  @ResponseBody
//  public AjaxResult getEddyProFileData(@RequestParam("filePath") String filePath,
//                                       @RequestParam("variableName") String variableName,
//                                       @RequestParam("lon") Float lon, @RequestParam("lat") Float lat,
//                                       @RequestParam("lonDiffer") Float lonDiffer, @RequestParam("latDiffer") Float latDiffer,
//                                       @RequestParam("degree") Float degree, @RequestParam("radianFlag") boolean radianFlag) {
//    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
//      return AjaxResult.success(profileService.getEddyProfileData(ncFile, variableName, lon, lat, lonDiffer, latDiffer, degree, radianFlag));
//    } catch (Exception e) {
//      e.printStackTrace();
//      return AjaxResult.error("获取剖面数据失败");
//    }
//  }

  @RequestMapping("/readJSon")
  @ResponseBody
  public AjaxResult readJson(@RequestParam("fileName") String fileName) {
    String jsonStr = "";
    try {
      File jsonFile = new File(fileName);
      FileReader fileReader = new FileReader(jsonFile);
      Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8);
      int ch = 0;
      StringBuffer sb = new StringBuffer();
      while ((ch = reader.read()) != -1) {
        sb.append((char) ch);
      }
      fileReader.close();
      reader.close();
      jsonStr = sb.toString();
      return AjaxResult.success("success", jsonStr);
    } catch (IOException e) {
      e.printStackTrace();
      return AjaxResult.error("数据读取错误");
    }
  }


  @RequestMapping("probJson")
  @RequestBody
  public static void createJson(JData jData) {
    BufferedWriter writer = null;
    System.out.println(new File("D:\\data\\1993强度月平均").exists());
    if (!new File("D:\\data\\1993强度月平均").exists()) {
      new File("D:\\data\\1993强度月平均").mkdirs();
    }

    File file = new File("D:\\data\\1993强度月平均\\" + jData.getFileName() + jData.getMonNumber() + ".json");
    //如果文件不存在，则新建一个
    if (!file.exists()) {
      try {
        file.createNewFile();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    //写入
    try {
      writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), "UTF-8"));
      writer.write(jData.getJsonData());
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (writer != null) {
          writer.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    System.out.println("文件写入成功！");
  }
}
